package com.cloud.job.snail;

import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
import com.cloud.api.domain.job.VehicleMileage;
import com.cloud.api.domain.model.VehicleModel;
import com.cloud.api.domain.screen.ModelExcept;
import com.cloud.api.domain.screen.ModelPortrait;
import com.cloud.api.domain.screen.VehicleBreakdown;
import com.cloud.api.myenum.AlarmTypeEnum;
import com.cloud.job.service.IModelPortraitService;
import com.cloud.job.service.IVehicleAlarmService;
import com.cloud.job.service.IVehicleMileageService;
import com.cloud.job.service.IVehicleModelService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 杨斌
 * 2024-12-2024-12-26
 */
@Component
@Slf4j
public class StatisticsAlarms {
    @Resource
    private IVehicleAlarmService vehicleAlarmService;

    @Resource
    private IModelPortraitService modelPortraitService;

    @Resource
    private IVehicleModelService vehicleModelService;

    @Resource
    private IVehicleMileageService vehicleMileageService;

    @Resource(name = "myRedis")
    private RedisTemplate<String, Object> redisTemplate;

    // 统计车辆每日运行数据
    @JobExecutor(name = "vehicle_alarm_data")
    public void getModelExcept() {
        //车型画像图片
        List<ModelPortrait> modelPortraits = modelPortraitService.list();
        List<VehicleModel> modelList = vehicleModelService.getLastModelList();
        List<VehicleBreakdown> vehicleBreakdowns = vehicleAlarmService.selectBreakdowns();
        List<VehicleMileage> vehicleMileage = vehicleMileageService.getVehicleMileage();

        Map<String, Map<String, List<VehicleBreakdown>>> groupedByModelIdAndCode = vehicleBreakdowns.stream()
                .collect(Collectors.groupingBy(VehicleBreakdown::getModelId,
                        Collectors.groupingBy(VehicleBreakdown::getCode)));
        Map<String, List<VehicleMileage>> collect = vehicleMileage.stream()
                .filter(v -> v.getModelId() != null)
                .collect(Collectors.groupingBy(VehicleMileage::getModelId));
        Map<String, List<ModelPortrait>> portraitMap = modelPortraits.stream().collect(Collectors.groupingBy(ModelPortrait::getModeId));

        List<ModelExcept> modelExcepts = new ArrayList<>();
        for (VehicleModel vehicleModel : modelList){
            ModelExcept modelExcept = new ModelExcept();
            modelExcept.setModelId(vehicleModel.getId());
            modelExcept.setModelName(vehicleModel.getModelName());
            List<ModelPortrait> modelPortrait = portraitMap.get(vehicleModel.getId());
            if (modelPortrait == null){
                //TODO 后期如果每个车型都有自己的图片需要修改为自己的，而不是统一的
                modelExcept.setPicUrl(modelPortraits.getFirst().getPicUrl());
                modelExcept.setItemConnectLine(modelPortraits.getFirst().getItemConnectLine());
            }else {
                ModelPortrait data = modelPortrait.get(0);
                modelExcept.setPicUrl(data.getPicUrl());
                modelExcept.setItemConnectLine(data.getItemConnectLine());
            }

            List<VehicleMileage> modelMileage = collect.get(vehicleModel.getId());
            if (modelMileage == null){
                modelExcept.setAccumulativeMileage(0L);
                modelExcept.setCumulativeChargePower(0L);
                modelExcept.setRunTime(0L);
            }
            else {
                VehicleMileage data = modelMileage.get(0);
                modelExcept.setAccumulativeMileage(data.getAccumulativeMileage());
                modelExcept.setCumulativeChargePower(data.getChargeCapacity());
                modelExcept.setRunTime(data.getRunTime());
            }
            Map<String, List<VehicleBreakdown>> codeBreaks = groupedByModelIdAndCode.get(vehicleModel.getId());
            List<VehicleBreakdown> breakdownList = new ArrayList<>();
            if (codeBreaks == null){
                for (int i = 1; i <= 19; i++) {
                    VehicleBreakdown vehicleBreakdown = new VehicleBreakdown();
                    vehicleBreakdown.setCode(String.valueOf(i));
                    vehicleBreakdown.setBreakCount(0L);
//                    List<AlarmCategory> alarmCategories = categoryMap.get(String.valueOf(i));
                    vehicleBreakdown.setName(AlarmTypeEnum.getDesc(i));
                    breakdownList.add(vehicleBreakdown);
                }
            }else {
                for (AlarmTypeEnum alarmTypeEnum : AlarmTypeEnum.values()){
                    Integer code = alarmTypeEnum.getValue();
                    VehicleBreakdown vehicleBreakdown = new VehicleBreakdown();
                    List<VehicleBreakdown> codeBreak = codeBreaks.get(String.valueOf(code));
                    vehicleBreakdown.setCode(String.valueOf(code));
                    vehicleBreakdown.setName(AlarmTypeEnum.getDesc(code));
                    if (codeBreak == null){
                        vehicleBreakdown.setBreakCount(0L);
                        breakdownList.add(vehicleBreakdown);
                        continue;
                    }
                    vehicleBreakdown.setBreakCount(codeBreak.get(0).getBreakCount());
                    breakdownList.add(vehicleBreakdown);
                }
            }
            modelExcept.setExceptCount(breakdownList);
            modelExcepts.add(modelExcept);
        }
        //给报警数据排序
        List<ModelExcept> modelExceptList = orderException(modelExcepts, vehicleBreakdowns);

//        String writeValueAsString = JsonUtils.writeValueAsString(modelExceptList);
//
//        System.out.println("writeValueAsString: " + writeValueAsString);

        redisTemplate.opsForValue().set("Vehicle:alarm",modelExceptList);
        log.info("存入redis成功");

    }

    public List<ModelExcept> orderException(List<ModelExcept> modelExcepts, List<VehicleBreakdown>vehicleBreakdowns){
        List<ModelExcept> newModelExcepts = new ArrayList<>();

        Map<String, ModelExcept> collect = modelExcepts.stream().collect(Collectors.toMap(ModelExcept::getModelId, Function.identity()));
        // 按照 modelid 分组，并统计每个 modelid 对应的 count 字段的总和
        Map<String, Long> breakdownCountSumByModelId = vehicleBreakdowns.stream()
                .collect(Collectors.groupingBy(
                        VehicleBreakdown::getModelId,   // 分组依据
                        Collectors.summingLong(VehicleBreakdown::getBreakCount)  // 计算每个分组中 count 字段的总和
                ));
        // 将 Map 转换为 List 并按值（count 总和）降序排序
        List<Map.Entry<String, Long>> sortedEntries = breakdownCountSumByModelId.entrySet().stream()
                .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
                .toList();

        for (Map.Entry<String, Long> entry : sortedEntries) {
            ModelExcept modelExcept = collect.get(entry.getKey());
            if (modelExcept != null){
                newModelExcepts.add(modelExcept);
            }
            collect.remove(entry.getKey());
        }
        //由于并不是所有的车型都报警，所以需要把未报警的车型数据补充进去
        for (String key : collect.keySet()){
            ModelExcept modelExcept = collect.get(key);
            newModelExcepts.add(modelExcept);
        }
        return newModelExcepts;
    }
}
